15987
19692
Ik heb per ongeluk de verkeerde bestanden naar Git gecommit, maar heb de commit nog niet naar de server gepusht.
Hoe kan ik die commits ongedaan maken vanuit de lokale repository? 
1
2
3
De volgende
Een vastlegging ongedaan maken en opnieuw uitvoeren
$ git commit -m "Iets verschrikkelijk misplaatst" # (0: Jouw ongeval)
$ git reset HEAD ~ # (1)
<< bewerk bestanden indien nodig >> # (2)
$ git add. # (3)
$ git commit -c ORIG_HEAD # (4)
Deze opdracht is verantwoordelijk voor het ongedaan maken. Het zal je laatste commit ongedaan maken terwijl je werkboom (de staat van je bestanden op schijf) onaangeroerd blijft. U moet ze opnieuw toevoegen voordat u ze opnieuw kunt vastleggen).
Breng correcties aan in werkende boombestanden.
git voeg alles toe dat je in je nieuwe commit wilt opnemen.
Voer de wijzigingen door en gebruik het oude vastleggingsbericht opnieuw. reset heeft de oude kop gekopieerd naar .git / ORIG_HEAD; commit met -c ORIG_HEAD zal een editor openen, die in eerste instantie het logbericht van de oude commit bevat en je deze kunt bewerken. Als u het bericht niet hoeft te bewerken, kunt u de optie -C gebruiken.
Als alternatief, om de vorige commit te bewerken (of alleen zijn commit-bericht), zal commit --amend veranderingen binnen de huidige index toevoegen aan de vorige commit.
Om een ​​commit die naar de server is gepusht te verwijderen (niet terugdraaien), is het herschrijven van de geschiedenis met git push origin master --force noodzakelijk.
Verder lezen
Hoe kan ik HEAD terug naar een vorige locatie verplaatsen? (Detached head) & Commits ongedaan maken
Het bovenstaande antwoord laat je git reflog zien, die je kunt gebruiken om de SHA-1 te bepalen voor de commit waarnaar je terug wilt keren. Zodra u deze waarde heeft, gebruikt u de reeks opdrachten zoals hierboven uitgelegd.
HEAD ~ is hetzelfde als HEAD ~ 1. Het artikel Wat is de HEAD in git? is handig als je meerdere commits ongedaan wilt maken.
|
Het ongedaan maken van een commit is een beetje eng als je niet weet hoe het werkt. Maar het is eigenlijk verbazingwekkend eenvoudig als je het begrijpt. Ik zal je de 4 verschillende manieren laten zien waarop je een commit ongedaan kunt maken.
optie 1: git reset --hard
Stel dat je dit hebt, waarbij C je HEAD is en (F) de staat van je bestanden.
(F)
ABC
↑
meester
Je wilt commit C vernietigen en het nooit meer zien en alle wijzigingen in lokaal gewijzigde bestanden verliezen. Jij doet dit:
git reset --hard HEAD ~ 1
Het resultaat is:
(F)
A-B
↑
meester
Nu is B het HOOFD. Omdat je --hard hebt gebruikt, worden je bestanden teruggezet naar hun staat bij commit B.
optie 2: git reset
Ah, maar stel dat commit C geen ramp was, maar gewoon een beetje afwijkend. Je wilt de commit ongedaan maken, maar je wijzigingen bewaren voor een beetje bewerken voordat je een betere commit doet. Vanaf hier opnieuw beginnen, met C als uw HOOFD:
(F)
ABC
↑
meester
U kunt dit doen, waarbij u de --hard laat:
git reset HEAD ~ 1
In dit geval is het resultaat:
(F)
ABC
↑
meester
In beide gevallen is HEAD slechts een pointer naar de laatste commit. Als je een git reset HEAD ~ 1 doet, vertel je Git om de HEAD-pointer één commit terug te zetten. Maar (tenzij u --hard gebruikt) laat u uw bestanden zoals ze waren. Dus nu laat git status de wijzigingen zien die je in C had ingecheckt. Je hebt niets verloren!
optie 3: git reset --soft
Voor de lichtste aanraking kun je zelfs je commit ongedaan maken, maar laat je bestanden en je index achter:
git reset --soft HEAD ~ 1
Dit laat niet alleen uw bestanden met rust, het laat zelfs uw index met rust. Als je git status doet, zul je zien dat dezelfde bestanden in de index staan ​​als voorheen. In feite, direct na dit commando, zou je git commit kunnen doen en zou je dezelfde commit opnieuw doen die je net had gedaan.
optie 4: je hebt git reset --hard gedaan en moet die code terughalen
Nog een ding: stel dat je een commit vernietigt zoals in het eerste voorbeeld, maar ontdek dan dat je het toch nodig had? Pech, toch?
Nee, er is nog steeds een manier om het terug te krijgen. Typ git reflog en je ziet een lijst met (gedeeltelijke) commit shas (dat wil zeggen, hashes) waar je naartoe bent verhuisd. Vind de commit die je vernietigd hebt, en doe dit:
git checkout -b someNewBranchName shaYouDestroyed
Je hebt die verplichting nu weer tot leven gewekt. Commits worden niet echt vernietigd in Git gedurende 90 dagen, dus je kunt meestal teruggaan en er een redden waar je niet vanaf wilde komen.
|
Er zijn twee manieren om je laatste commit "ongedaan te maken", afhankelijk van of je je commit al of niet openbaar hebt gemaakt (gepusht naar je remote repository):
Hoe een lokale commit ongedaan te maken
Laten we zeggen dat ik lokaal heb gepleegd, maar nu wil ik die commit verwijderen.
git log
commit 101: slechte commit # Laatste vastlegging. Dit zou 'HEAD' worden genoemd.
commit 100: goede commit # Tweede na laatste commit. Dit is degene die we willen.
Om alles terug te zetten naar de manier waarop het was voor de laatste commit, moeten we resetten naar de commit voor HEAD:
git reset --soft HEAD ^ # Gebruik --soft als je je wijzigingen wilt behouden
git reset --hard HEAD ^ # Gebruik --hard als het je niet uitmaakt de aangebrachte wijzigingen te behouden
Nu zal git log laten zien dat onze laatste commit is verwijderd.
Hoe u een openbare vastlegging ongedaan kunt maken
Als je je commits al openbaar hebt gemaakt, wil je een nieuwe commit maken die de wijzigingen die je in je vorige commit (huidige HEAD) hebt gemaakt, "terugdraait".
git terugzetten HEAD
Uw wijzigingen worden nu teruggedraaiden klaar voor u om te plegen:
git commit -m 'het bestand herstellen dat ik per ongeluk heb verwijderd'
git log
commit 102: het bestand herstellen dat ik per ongeluk heb verwijderd
commit 101: een bestand verwijderen dat we niet nodig hebben
commit 100: een bestand toevoegen dat we nodig hebben
Voor meer informatie, ga naar Git Basics - Undoing Things.
|
Bestanden toevoegen / verwijderen om de dingen naar wens te krijgen:
git rm classdir
git add sourcedir
Wijzig vervolgens de commit:
git commit --amend
De vorige, foutieve commit zal worden bewerkt om de nieuwe indexstatus weer te geven - met andere woorden, het zal zijn alsof je in de eerste plaats nooit de fout hebt gemaakt.
Merk op dat u dit alleen moet doen als u nog niet heeft gepusht. Als je hebt gepusht, moet je gewoon een fix normaal vastleggen.
|
git rm uw bestanden / *. class
git commit -a -m "verwijderde alle klassebestanden in de map 'jouwbestanden'"
of
git reset --hard HEAD ~ 1
Waarschuwing: het bovenstaande commando verwijdert permanent de wijzigingen aan de .java-bestanden (en alle andere bestanden) die u wilde vastleggen.
De harde reset naar HEAD-1 zal je werkkopie in de staat van de commit zetten voor je verkeerde commit.
|
Om de laatste commit te wijzigen
Vervang de bestanden in de index:
git rm --cached * .class
git add * .java
Wijzig vervolgens de commit als het een privé-branch is:
git commit --amend
Of, als het een gedeelde branch is, maak een nieuwe commit:
git commit -m 'Vervang .class-bestanden door .java-bestanden'
(Gebruik de geweldige interactieve rebase om een ​​eerdere commit te wijzigen.)
ProTip ™: Voeg * .class toe aan een gitignore om te voorkomen dat dit opnieuw gebeurt.
Om een ​​vastlegging ongedaan te maken
Het wijzigen van een commit is de ideale oplossing als je de laatste commit moet wijzigen, maar een meer algemene oplossing wordt gereset.
Je kunt Git resetten naar elke commit met:
git reset @ ~ N
Waar N het aantal commits is voor HEAD, en @ ~ reset naar de vorige commit.
Dus in plaats van de commit te wijzigen, zou je kunnen gebruiken:
git reset @ ~
git add * .java
git commit -m ".java-bestanden toevoegen"
Bekijk git help reset, met name de secties over --soft --mixed en --hard, voor een beter begrip van wat dit doet.
Opnieuw loggen
Als je het verprutst, kun je altijd de reflog gebruiken om achtergelaten commits te vinden:
$ git reset @ ~
$ git reflog
c4f708b HEAD @ {0}: reset: verhuizen naar @ ~
2c52489 HEAD @ {1}: commit: enkele .class-bestanden toegevoegd
$ git reset 2c52489
... en je bent terug waar je begon
|
Gebruik git revert .
Gebruik git log om de commit-ID te krijgen.
|
Als je van plan bent om een ​​lokale commit volledig ongedaan te maken, wat je ook verandert, heb je tijdens de commit gedaan, en als je je daar geen zorgen over maakt, voer je gewoon het volgende commando uit.
git reset --hard HEAD ^ 1
(Dit commando negeert je hele commit en je wijzigingen gaan volledig verloren uit je lokale werkboom). Als je je commit ongedaan wilt maken, maar je wilt je wijzigingen in het staging-gebied (voor commit, net als na git add), voer dan het volgende commando uit.
git reset --soft HEAD ^ 1
Nu komen uw toegewezen bestanden in het verzamelgebied. Stel dat u de bestanden upstage wilt omdat u verkeerde inhoud moet bewerken, voer dan de volgende opdracht uit
git reset HEAD
Nu moeten de vastgelegde bestanden van het geënsceneerde gebied naar het niet-geënsceneerde gebied komen. Nu zijn bestanden klaar om te bewerken, dus wat je ook verandert, je wilt gaan bewerken en toevoegen en een nieuwe / nieuwe commit doen.
Meer (link verbroken) (gearchiveerde versie)
|
Als je Git Extras hebt geïnstalleerd, kun je git undo uitvoeren om de laatste commit ongedaan te maken. git undo 3 zal de laatste drie commits ongedaan maken.
|
Ik wilde de laatste vijf commits in onze gedeelde repository ongedaan maken. Ik heb de revisie-ID opgezocht waarnaar ik wilde terugdraaien. Toen typte ik het volgende in.
prompt> git reset --hard 5a7404742c85
HEAD staat nu op 5a74047 Nog een pagina aan de catalogus toegevoegd
prompt> git push oorsprong master --force
Totaal 0 (delta 0), hergebruikt 0 (delta 0)
remote: bb / acl: neoneye is toegestaan. geaccepteerde laadvermogen.
Naar git@bitbucket.org: thecompany / prometheus.git
+ 09a6480 ... 5a74047 master -> master (gedwongen update)
prompt>
|
Ik gebruik liever git rebase -i voor deze job, omdat er een mooie lijst verschijnt waarin ik de commits kan kiezen die ik wil verwijderen. Het is misschien niet zo direct als sommige andere antwoorden hier, maar het voelt gewoon goed.
Kies hoeveel commits je wilt vermelden, en roep dan op deze manier aan (om de laatste drie in te schakelen)
git rebase -i HEAD ~ 3
Sample lijst
kies aa28ba7 Sanity check voor RtmpSrv-poort
kies de optie c26c541 RtmpSrv-versie
kies 58d6909 Betere ondersteuning voor URL-decodering
Dan zal Git commits verwijderen voor elke regel die je verwijdert.
|
Hoe de vorige lokale commit te herstellen
Gebruik git-gui (of vergelijkbaar) om een ​​git commit --amend uit te voeren. Vanuit de GUI kun je individuele bestanden toevoegen aan of verwijderen uit de commit. U kunt ook het vastlegbericht wijzigen.
Hoe de vorige lokale commit ongedaan kan worden gemaakt
Reset gewoon je branch naar de vorige locatie (bijvoorbeeld door gitk of git rebase te gebruiken). Pas vervolgens uw wijzigingen opnieuw toe vanuit een opgeslagen kopie. Na garbage collection in uw lokale repository, zal het zijn alsof de ongewenste commit nooit heeft plaatsgevonden. Om dat allemaal in een enkel commando te doen, gebruik je git reset HEAD ~ 1.
Woordwaarschuwing: Onzorgvuldig gebruik van git reset is een goede manier om je werkkopie in een verwarrende staat te krijgen. Ik raad Git-beginners aan om dit te vermijden als ze kunnen.
Hoe u een openbare vastlegging ongedaan kunt maken
Voer een omgekeerde cherry pick (git-revert) uit om de wijzigingen ongedaan te maken.
Als je nog geen andere wijzigingen naar je filiaal hebt getrokken, kun je gewoon doen ...
git revert --no-edit HEAD
Push vervolgens uw bijgewerkte branch naar de gedeelde repository.
De commit geschiedenis zal beide commits afzonderlijk tonen.
Geavanceerd: correctie van de privétak in de openbare opslagplaats
Dit kan gevaarlijk zijn - zorg ervoor dat je een lokale kopie van de branch hebt om opnieuw te pushen.
Let ook op: u wilt dit niet doen als iemand anders op de branch werkt.
git push --delete (branch_name) ## verwijder publieke versie van branch
Ruim je filiaal lokaal op en herhaal ...
git push oorsprong (branch_name)
In het normale geval hoeft u zich waarschijnlijk geen zorgen te maken dat uw privé-branch commit-geschiedenis ongerept is. Druk gewoon op een follow-up commit (zie 'Hoe een openbare commit ongedaan maken' hierboven), en doe later een squash-merge om de geschiedenis te verbergen.
|
Als je het permanent ongedaan wilt maken en je hebt een repository gekloond
De commit-id kan worden gezien door
git log
Dan kun je doen -
git reset --hard 
git push oorsprong  -f
|
Als je rommel hebt gepleegd maar niet hebt gepusht,
git reset --soft HEAD ~ 1
HEAD ~ 1 is een afkorting voor de commit voor head. Als alternatief kunt u verwijzen naar de SHA-1 van de hash als u wilt resetten naar. --soft optie zal de commit verwijderen, maar het laat al je gewijzigde bestanden "Changes to be commit", zoals git status het zou omschrijven.
Als je alle wijzigingen in de getraceerde bestanden in de werkende boom wilt verwijderen sinds de commit voor de head, gebruik dan "--hard".
OF
Als je al hebt gepusht en iemand heeft getrokken, wat meestal mijn geval is, kun je git reset niet gebruiken. Je kunt echter een git revert doen,
git terugzetten HEAD
Dit zal een nieuwe commit maken die alles terugdraait dat door de onbedoelde commit is geïntroduceerd.
|
Op SourceTree (GUI voor GitHub) kun je met de rechtermuisknop op de commit klikken en een 'Reverse Commit' uitvoeren. Dit zou uw wijzigingen ongedaan moeten maken.
Op de terminal:
U kunt ook gebruik maken van:
git revert
Of:
git reset --soft HEAD ^ # Gebruik --soft als je je wijzigingen wilt behouden.
git reset --hard HEAD ^ # Gebruik --hard als het je niet uitmaakt je wijzigingen te behouden.
|
Een enkele opdracht:
git reset --soft 'HEAD ^'
Het werkt geweldig om de laatste lokale commit ongedaan te maken!
|
Reset het gewoon door het onderstaande commando te gebruiken met git:
git reset --soft HEAD ~ 1
Leg uit: wat git reset doet, het is in feite gereset naar elke commit waar je naar terug zou willen gaan, en als je het combineert met --soft key, zal het teruggaan, maar de wijzigingen in je bestand (en) behouden, dus je gaat terug naar het stadium waarin het bestand zojuist is toegevoegd, HEAD is de kop van de branch en als je combineert met ~ 1 (in dit geval gebruik je ook HEAD ^), zal het slechts één commit teruggaan die je wilt. ..
Ik maak de stappen in de onderstaande afbeelding in meer details voor je, inclusief alle stappen die in echte situaties kunnen gebeuren en het vastleggen van de code:
|
Hoe de laatste Git-commit ongedaan maken?
Om alles terug te zetten naar de manier waarop het was voor de laatste commit, moeten we resetten naar de commit voor HEAD.
Als u uw aangebrachte wijzigingen niet wilt behouden:
git reset --hard HEAD ^
Als u uw wijzigingen wilt behouden:
git reset --soft HEAD ^
Controleer nu je git-log. Het zal laten zien dat onze laatste commit is verwijderd.
|
"Reset de werkende boom naar de laatste vastlegging"
git reset --hard HEAD ^
"Verwijder onbekende bestanden uit de werkende boom"
git schoon
zie - Git Quick Reference
OPMERKING: dit commando zal je vorige commit verwijderen, dus wees voorzichtig! git reset --hard is veiliger.
|
Gebruik reflog om een ​​juiste staat te vinden
git reflog
REFLOG VOORDAT RESET
Selecteer het juiste reflog (in mijn geval f3cb6e2) en typ
git reset --hard f3cb6e2
Daarna wordt de repo HEAD gereset naar die HEADid
LOG NA RESET
Eindelijk ziet de reflog eruit zoals op de onderstaande afbeelding
REFLOG DEFINITIEF
|
Eerste loop:
git reflog
Het zal je alle mogelijke acties laten zien die je hebt uitgevoerd op je repository, bijvoorbeeld commit, merge, pull, etc.
Dan doen:
git reset --hard ActionIdFromRefLog
|
Laatste vastlegging ongedaan maken:
git reset --soft HEAD ^ of git reset --soft HEAD ~
Dit zal de laatste commit ongedaan maken.
Hier betekent --soft het resetten naar enscenering.
HEAD ~ of HEAD ^ betekent verplaatsen naar commit voor HEAD.
Vervang de laatste commit naar een nieuwe commit:
git commit --amend -m "bericht"
Het zal de laatste commit vervangen door de nieuwe commit.
|
Een andere manier:
Check de branch uit die je wilt terugzetten, en reset dan je lokale werkkopie terug naar de commit waarvan je de laatste wilt zijn op de externe server (alles daarna gaat vaarwel). Om dit te doen, klikte ik in SourceTree met de rechtermuisknop op en selecteerde "BRANCHNAME resetten naar deze commit".
Navigeer vervolgens naar de lokale map van uw repository en voer deze opdracht uit:
git -c diff.mnemonicprefix = false -c core.quotepath = false push -v -f --tags REPOSITORY_NAMEBRANCHNAME: BRANCHNAME
Dit zal alle commits na de huidige in je lokale repository wissen, maar alleen voor die ene branch.
|
Typ git log en zoek de hashcode van de laatste commit en voer dan in:
git reset 
|
In mijn geval heb ik per ongeluk bestanden vastgelegd die ik niet wilde. Dus ik deed het volgende en het werkte:
git reset --soft HEAD ^
git rm --cached [bestanden die je niet nodig hebt]
git add [bestanden die je nodig hebt]
git commit -c ORIG_HEAD
Controleer de resultaten met gitk of git log --stat
|
Eenvoudig, voer dit uit op uw opdrachtregel:
git reset --soft HEAD ~
|
Er zijn twee hoofdscenario's
Je hebt de commit nog niet gepusht
Als het probleem extra bestanden waren die je hebt gecommit (en je wilt die niet in de repository), kun je ze verwijderen met git rm en dan commiting met --amend
git rm 
Je kunt ook hele mappen verwijderen met -r, of zelfs combineren met andere Bash-opdrachten
git rm -r 
git rm $ (vind -naam '* .class')
Na het verwijderen van de bestanden, kun je vastleggen, met de optie --amend
git commit --amend -C HEAD # de -C optie is om hetzelfde vastlegbericht te gebruiken
Dit zal je recente lokale commit herschrijven en de extra bestanden verwijderen, dus deze bestanden zullen nooit bij push worden verzonden en zullen ook door GC uit je lokale .git-repository worden verwijderd.
Je hebt de commit al gepusht
Je kunt dezelfde oplossing van het andere scenario toepassen en dan git push doen met de optie -f, maar het wordt niet aanbevolen omdat het de geschiedenis op afstand overschrijft met een afwijkende wijziging (het kan je repository verpesten).
In plaats daarvan moet je de commit doen zonder --amend (onthoud dit over -amend`: die optie herschrijft de geschiedenis van de laatste commit).
|
Voor een lokale verplichting
git reset --soft HEAD ~ 1
of als je niet precies weet in welke commit het is, zou je kunnen gebruiken
git rm --cached 
Voor een geduwde commit
De juiste manier om bestanden uit de repository-geschiedenis te verwijderen, is door git filter-branch te gebruiken. Dat is,
git filter-branch --index-filter 'git rm --cached ' HEAD
Maar ik raad u aan om dit commando met zorg te gebruiken. Lees meer op git-filter-branch (1) Manual Page.
|
Om terug te zetten naar de vorige revisie, permanent alle niet-vastgelegde wijzigingen verwijderen:
git reset --hard HEAD ~ 1
|
WAT TE GEBRUIKEN, reset --soft of reset --hard?
Ik tel gewoon twee cent op voor het antwoord van @ Kyralessa:
Als je niet zeker weet wat je moet gebruiken, ga dan voor --soft (ik heb deze conventie gebruikt om het te onthouden --soft voor de zekerheid).
Waarom ?
Als u - per ongeluk hard kiest, verliest u uw wijzigingen zoals voorheen.
Als u per ongeluk --soft kiest, kunt u dezelfde resultaten als --hard bereiken door extra opdrachten toe te passen
git reset HEAD file.html
git checkout - file.html
Volledig voorbeeld
echo "enkele wijzigingen ..."> file.html
git add file.html
git commit -m "verkeerde commit"
# Ik moet resetten
git reset --hard HEAD ~ 1 (wijzigingen annuleren)
# OF
git reset --soft HEAD ~ 1 # Terug naar staging
git reset HEAD file.html # terug naar werkmap
git checkout - file.html # annuleer wijzigingen
Credits gaan naar @Kyralessa.
|
1
2
3
De volgende
Zeer actieve vraag. Verdien 10 reputatie om deze vraag te beantwoorden. De reputatievereiste helpt deze vraag te beschermen tegen spam en niet-beantwoording.
Niet het antwoord waar je naar zoekt? Blader door andere vragen met de tag git version-control git-commit undo of stel je eigen vraag.